package da;

import data.Building;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;
import java.util.ResourceBundle;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Class BuildingDA
 * 
 * Data Accessor for Building objects.
 * 
 * @author Stijn Verslycken, Jonas Van Den Bossche
 * @date 2007-2008
 */
public class BuildingDA {

    private ResourceBundle bundle;
    private static BuildingDA instance = null;

    private BuildingDA() {
        bundle = ResourceBundle.getBundle("da.dbconsts");
    }

    public static BuildingDA getInstance() {
        if (instance == null) {
            instance = new BuildingDA();
        }
        return instance;
    }

    // <editor-fold desc="SELECTS" defaultstate="collapsed">
    /**
     * Fetches all buildings of a given village
     * @param villageId
     * @return list of buildings
     */
    public Vector<Building> getAllBuildingsOfVillage(int villageId) {
        Vector<Building> buildings = null;
        Building building = null;

        String sql = bundle.getString("getAllBuildingsOfVillage");

        Connection dbcon = null;
        try {
            dbcon = DatabaseConnection.getInstance().getConnection();
            PreparedStatement prepstat = dbcon.prepareStatement(sql);
            try {
                prepstat.setInt(1, villageId);
                ResultSet rs = prepstat.executeQuery();

                buildings = new Vector<Building>();
                while (rs.next()) {


                    building = new Building(rs.getInt("building_id"), rs.getString("name"),
                            rs.getInt("level"), rs.getInt("max_level"), rs.getInt("time_left"), rs.getInt("cost_food"),
                            rs.getInt("cost_wood"), rs.getInt("cost_stone"), rs.getInt("cost_iron"),
                            rs.getInt("cost_gold"), rs.getString("status_description"),
                            rs.getInt("village_id"), rs.getInt("location_x"),
                            rs.getInt("location_y"), rs.getInt("capacity"), rs.getInt("strength"),
                            rs.getString("resource_type"), rs.getInt("type"), rs.getString("image_url"));


                    // add building to list of buildings
                    buildings.add(building);
                }

            } finally {
                prepstat.close();
                dbcon.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(BuildingDA.class.getName()).log(Level.SEVERE, null, ex);
            System.err.println("getAllBuildingsOfVillage error -->" + ex.toString());
        }

        return buildings;
    }

    /**
     * Fetches a building of a given village by its position.
     * @param villageId
     * @param positionX
     * @param positionY
     * @return building
     */
    public Building getBuildingByPosition(int villageId, int positionX, int positionY) {
        Building building = null;

        String sql = bundle.getString("getBuildingByPosition");

        Connection dbcon = null;
        try {
            dbcon = DatabaseConnection.getInstance().getConnection();
            PreparedStatement prepstat = dbcon.prepareStatement(sql);
            try {
                prepstat.setInt(1, villageId);
                prepstat.setInt(2, positionX);
                prepstat.setInt(3, positionY);
                ResultSet rs = prepstat.executeQuery();

                while (rs.next()) {

                    building = new Building(rs.getInt("building_id"), rs.getString("name"),
                            rs.getInt("level"), rs.getInt("max_level"), rs.getInt("time_left"), rs.getInt("cost_food"),
                            rs.getInt("cost_wood"), rs.getInt("cost_stone"), rs.getInt("cost_iron"),
                            rs.getInt("cost_gold"), rs.getString("status_description"),
                            rs.getInt("village_id"), rs.getInt("location_x"),
                            rs.getInt("location_y"), rs.getInt("capacity"), rs.getInt("strength"),
                            rs.getString("resource_type"), rs.getInt("type"), rs.getString("image_url"));
                }
            } finally {
                prepstat.close();
                dbcon.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(BuildingDA.class.getName()).log(Level.SEVERE, null, ex);
            System.err.println("getBuildingByPosition error -->" + ex.toString());
        }

        return building;
    }

    public Vector<Building> getBuildingsByVillageIdResourceTypeName(int villageId, String resourceTypeName) {
        Vector<Building> buildings = null;
        Building building = null;

        String sql = bundle.getString("getBuildingsByVillageIdBuildingType");

        Connection dbcon = null;
        try {
            dbcon = DatabaseConnection.getInstance().getConnection();
            PreparedStatement prepstat = dbcon.prepareStatement(sql);
            try {
                prepstat.setInt(1, villageId);
                prepstat.setString(2, resourceTypeName);
                ResultSet rs = prepstat.executeQuery();

                buildings = new Vector<Building>();
                while (rs.next()) {

                    building = new Building(rs.getInt("building_id"), rs.getString("name"),
                            rs.getInt("level"), rs.getInt("max_level"), rs.getInt("time_left"), rs.getInt("cost_food"),
                            rs.getInt("cost_wood"), rs.getInt("cost_stone"), rs.getInt("cost_iron"),
                            rs.getInt("cost_gold"), rs.getString("status_description"),
                            rs.getInt("village_id"), rs.getInt("location_x"),
                            rs.getInt("location_y"), rs.getInt("capacity"), rs.getInt("strength"),
                            rs.getString("resource_type"), rs.getInt("type"), rs.getString("image_url"));


                    // add building to list of buildings
                    buildings.add(building);
                }

            } finally {
                prepstat.close();
                dbcon.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(BuildingDA.class.getName()).log(Level.SEVERE, null, ex);
            System.err.println("getBuildingsByVillageIdBuildingType error -->" + ex.toString());
        }

        return buildings;
    }

    // </editor-fold>
    // <editor-fold desc="INSERTS" defaultstate="collapsed">
    /**
     * Adds a building to the DB.
     * @param b
     */
    public void addBuilding(Building b) {

        String sql = bundle.getString("addBuilding");

        Connection dbcon = null;
        try {
            dbcon = DatabaseConnection.getInstance().getConnection();
            PreparedStatement prepstat = dbcon.prepareStatement(sql);
            try {
                // Adds data to table "building"
                prepstat.setString(1, b.getName());
                prepstat.setInt(2, b.getLevel());
                prepstat.setInt(3, b.getMaxLevel());
                prepstat.setInt(4, b.getTimeLeft());
                prepstat.setInt(5, b.getFoodCost());
                prepstat.setInt(6, b.getWoodCost());
                prepstat.setInt(7, b.getStoneCost());
                prepstat.setInt(8, b.getIronCost());
                prepstat.setInt(9, b.getGoldCost());
                prepstat.setString(10, b.getStatusDescription());
                prepstat.setInt(11, b.getVillageId());
                prepstat.setInt(12, b.getLocationX());
                prepstat.setInt(13, b.getLocationY());
                prepstat.setInt(14, b.getCapacity());
                prepstat.setInt(15, b.getStrength());
                prepstat.setString(16, b.getResourceType());
                prepstat.setInt(17, b.getType());
                prepstat.setString(18, b.getImageUrl());

                prepstat.executeUpdate();

            } finally {
                prepstat.close();
                dbcon.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(BuildingDA.class.getName()).log(Level.SEVERE, null, ex);
            System.err.println("addBuilding error -->" + ex.toString());
        }
    }

    // </editor-fold>

    // <editor-fold desc="UPDATES" defaultstate="collapsed">
    /**
     * Updates an existing building.     * 
     * @param b
     */
    public void editBuilding(Building b) {
        String sql = bundle.getString("editBuilding");
        Connection dbcon = null;
        try {
            dbcon = DatabaseConnection.getInstance().getConnection();
            PreparedStatement prepstat = dbcon.prepareStatement(sql);
            try {
                // Updates table "building"
                prepstat.setString(1, b.getName());
                prepstat.setInt(2, b.getLevel());
                prepstat.setInt(3, b.getMaxLevel());
                prepstat.setInt(4, b.getTimeLeft());
                prepstat.setInt(5, b.getFoodCost());
                prepstat.setInt(6, b.getWoodCost());
                prepstat.setInt(7, b.getStoneCost());
                prepstat.setInt(8, b.getIronCost());
                prepstat.setInt(9, b.getGoldCost());
                prepstat.setString(10, b.getStatusDescription());
                prepstat.setInt(11, b.getVillageId());
                prepstat.setInt(12, b.getLocationX());
                prepstat.setInt(13, b.getLocationY());
                prepstat.setInt(14, b.getCapacity());
                prepstat.setInt(15, b.getStrength());
                prepstat.setString(16, b.getResourceType());
                prepstat.setInt(17, b.getType());
                prepstat.setString(18, b.getImageUrl());
                prepstat.setInt(19, b.getBuildingId());

                prepstat.executeUpdate();


            } finally {
                prepstat.close();
                dbcon.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(BuildingDA.class.getName()).log(Level.SEVERE, null, ex);
            System.err.println("editBuilding error -->" + ex.toString());
        }
    }

    // </editor-fold>

    // <editor-fold desc="DELETES" defaultstate="collapsed">
    /**
     * Removes the building with given id from the DB.
     * @param buildingId 
     */
    public void removeBuilding(int buildingId) {
        String sql = bundle.getString("removeBuilding");
        Connection dbcon = null;
        try {
            dbcon = DatabaseConnection.getInstance().getConnection();
            PreparedStatement prepstat = dbcon.prepareStatement(sql);
            try {
                // Deletes from table "building"
                prepstat.setInt(1, buildingId);
                prepstat.executeUpdate();

            } finally {
                prepstat.close();
                dbcon.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(BuildingDA.class.getName()).log(Level.SEVERE, null, ex);
            System.err.println("removeBuilding error -->" + ex.toString());
        }
    }
    // </editor-fold>
}
